#ifndef FIELD_HEADER_VIZMF_PROJECT
#define FIELD_HEADER_VIZMF_PROJECT

#include <string>
#include <vector>
#include <utility>
#include "src/core/workspace/lattice.h"

struct FieldNode
{
  typedef float float_type;
  typedef Lattice::point_type point_type;
public:
  FieldNode(const point_type p, const float_type v) : point(p), value(v) {}
  point_type point;
  float_type value;
};

/*
  VizMF Field class
*/

class Field {
public:
  typedef unsigned int int_type;
  typedef std::string string;
  typedef FieldNode::float_type float_type;
private:
  typedef std::vector<float_type> VF;
public:
//  for now it seems only const iterators are needed
//  typedef VF::iterator values_iterator;
  typedef VF::const_iterator values_const_iterator;
//  typedef Lattice::points_iterator points_iterator;
  typedef Lattice::points_const_iterator points_const_iterator;

public:
  Field(int_type num = 0, const string& name = string(), const Lattice* lattice = 0, const VF& values = VF())
    : number_(num), name_(name), lattice_(lattice), values_(values) {}

  void setId(const int_type n) { number_ = n; }
  int_type id() const { return number_; }

  void setName(const string& s) { name_ = s; }
  const string& name() const { return name_; }

  void setLattice(const Lattice* lattice) { lattice_ = lattice; }
  const Lattice* lattice() const { return lattice_; }

  void addValue(const float_type value) { values_.push_back(value); }

//  values_iterator valuesBegin() { return values_.begin(); }
//  values_iterator valuesEnd() { return values_.end(); }
  values_const_iterator valuesBegin() const { return values_.begin(); }
  values_const_iterator valuesEnd() const { return values_.end(); }
//  points_iterator pointsBegin() { return lattice_.pointsBegin(); }
//  points_iterator pointsEnd() { return lattice_.pointsEnd(); }
  points_const_iterator pointsBegin() const { return lattice_->pointsBegin(); }
  points_const_iterator pointsEnd() const { return lattice_->pointsEnd(); }

  int_type count() const { return lattice_->count(); }

  FieldNode operator [] (const int_type i ) const { return FieldNode((*lattice_)[i], values_[i]); }

  void reserve(const int_type n) { values_.reserve(n);}

private:
  int_type number_;
  string name_;
  const Lattice* lattice_;	// for whose points the values are determined
  VF values_;
};

#endif // FIELD_HEADER_VIZMF_PROJECT
